package orchestration

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/hypervisors"
	"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/services"
	"openstack_api/client"
)

type MyHypervisor struct {
	hypervisors.Hypervisor
	IsMaster string `json:"is_master"`
	ID       string `json:"id"`
}

type UpdateHypervisor struct {
	Disable       string `json:"disable"`
	DisableReason string `json:"disable_reason,omitempty"`
}

// GetHyperService 获取各个节点的虚拟化信息，并通过计算services的数量来表示是否是主节点
func GetHyperService(c *gin.Context) {
	extractHypervisors := getHypervisor()
	fmt.Println(extractHypervisors)
	var myHypervisors []MyHypervisor
	for _, h := range extractHypervisors {
		sers := getServices(h.HypervisorHostname, "")
		if len(sers) > 1 {
			myHypervisors = append(myHypervisors, MyHypervisor{h, "true", h.ID})
		} else {
			myHypervisors = append(myHypervisors, MyHypervisor{h, "false", h.ID})
		}
	}
	c.JSON(200, myHypervisors)
}

func getHypervisor() []hypervisors.Hypervisor {
	computeClient := client.GetServerClient()
	computeClient.Microversion = "2.53"
	pager, _ := hypervisors.List(computeClient, hypervisors.ListOptsBuilder(hypervisors.ListOpts{})).AllPages()
	extractHypervisors, _ := hypervisors.ExtractHypervisors(pager)
	return extractHypervisors
}

func getServices(hostname string, binary string) []services.Service {
	computeClient := client.GetServerClient()
	computeClient.Microversion = "2.53"
	opts := services.ListOpts{}
	if hostname != "" {
		opts.Host = hostname
	}
	if binary != "" {
		opts.Binary = binary
	}
	ss, _ := services.List(computeClient, services.ListOptsBuilder(opts)).AllPages()
	sers, _ := services.ExtractServices(ss)
	return sers
}

// UpdateHyperService 设置节点的可用性
func UpdateHyperService(c *gin.Context) {
	computeClient := client.GetServerClient()
	computeClient.Microversion = "2.53"
	hid := c.Param("host_id")
	hypervisor, err := hypervisors.Get(computeClient, hid).Extract()
	if err != nil {
		c.JSON(404, err.Error())
		return
	}
	serviceID := ""
	sers := getServices(hypervisor.HypervisorHostname, "nova-compute")
	if len(sers) == 1 {
		serviceID = sers[0].ID
	}
	var up UpdateHypervisor
	err = c.ShouldBindJSON(&up)
	opts := services.UpdateOpts{}
	if up.Disable == "true" {
		//opts := services.UpdateOpts{
		//	Status:         services.ServiceDisabled,
		//	DisabledReason: up.DisableReason,
		//}
		opts.Status = services.ServiceDisabled
		opts.DisabledReason = up.DisableReason
	}
	service, err := services.Update(computeClient, serviceID, opts).Extract()
	if err != nil {
		c.JSON(400, err.Error())
		return
	}
	c.JSON(202, service)
}
